package manager.qrcode;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.beans.BeansException;

import com.fasterxml.jackson.core.JsonProcessingException;

import database.DBService;
import database.UserRechargeDBServer;
import database.pojo.UserRechargeInfo;
import io.netty.channel.ChannelFuture;
import manager.connection.ClientConnectionManager;
import manager.http.HttpClient;
import manager.pay.GetMidTradePackage;
import manager.pay.GetPayResult;
import manager.pay.state.ConsumptionType;
import manager.pay.state.PayState;
import manager.pay.state.PayType;
import manager.pay.type.GetMidTradePackageInfo;
import manager.pay.type.PayResultInfo;
import manager.qrcode.type.GetPayQRCodeInfo;
import net.socket.server.SocketServer;
import net.socket.server.protocal.PROTOID;
import net.socket.server.request.IRequest;
import net.socket.server.request.KCoinRechargeRequest;
import net.socket.server.request.PayQRCodeRequest;
import net.socket.server.response.KCoinRechargeResponse;
import net.socket.server.response.PayQRCodeResponse;
import observable.subject.MessageCenter;
import util.MyFactory;
import util.ResultTypeList;

public class GetPayQRCode {
	private ClientConnectionManager ccm = null;
	private GetMidTradePackage GMTP =null;
	
	
	
	public void init() {
		MessageCenter mc = MyFactory.context.getBean("MessageCenter", MessageCenter.class);
		mc.register(PROTOID.PAY_QRCODE_REQ, (int cmd, IRequest request)->PayQRCode(cmd, request));
		mc.register(PROTOID.KCOIN_RECHARGE_REQ, (int cmd,IRequest request)->HandleKCoinRecharge(cmd,request));
		
		
		ccm = MyFactory.context.getBean("ClientConnectionManager", ClientConnectionManager.class);
		GMTP = MyFactory.context.getBean("GetMidTradePackage", GetMidTradePackage.class);
		
	}

	private UserRechargeInfo initUserRechargeInfoOfKCoin(KCoinRechargeRequest req, int paytype) {
		UserRechargeInfo uInfo = new UserRechargeInfo();
		int uid;
		try {
			uid = MyFactory.context.getBean("DBService", DBService.class).getUidByOpenId(req.getOpenId());
		} catch (BeansException | SQLException e) {
			System.out.println("initUserRechargeInfoOfKCoin getUidByOpenId :"+e);
			return null;
		}
		uInfo.setMid(req.getMachineId());
		uInfo.setMount(req.getkCoin()/10);
		uInfo.setUid(uid);
		uInfo.setRecharge_status(PayState.WAITPAY);
		uInfo.setRecharge_type(paytype);
		uInfo.setRecharge_description("充值"+req.getkCoin()+"个k币");
		String out_trade_no = System.currentTimeMillis()+Integer.toString(uid);
		uInfo.setRecharge_orderid(out_trade_no);
		return uInfo;
	}



	private int PayQRCode(int cmd, IRequest request) throws IllegalArgumentException, IllegalAccessException, BeansException, ClientProtocolException, SQLException, URISyntaxException, IOException {
		PayQRCodeRequest req = (PayQRCodeRequest)request;
		if("".equals(req.getOpenId())||-1==req.getPacketId()) {
			KCoinRechargeResponse rsp = new KCoinRechargeResponse();
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		switch (req.getPayType()) {
			case PayType.WXPay:
				getWXPayQRCode(req);
				break;			
			case PayType.ALIPAY:
				getAliPayQRcode(req);
				break;		
			case PayType.KPAY:
				handleKpay(req);
			default:
				KCoinRechargeResponse rsp = new KCoinRechargeResponse();
				rsp.setResult(ResultTypeList.ERROR_ARGS);
				ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
				return ResultTypeList.ERROR_ARGS;
		}
		return 1;
	}

	private int HandleKCoinRecharge(int cmd, IRequest request) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		KCoinRechargeRequest req = (KCoinRechargeRequest)request;
		KCoinRechargeResponse rsp = new KCoinRechargeResponse();
		if(req.getkCoin()==0||req.getPayType()==0||"".equals(req.getOpenId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		if(req.getPayType()==PayType.ALIPAY) {
			getKCoinQRCodeOfAli(req);
		}else if (req.getPayType() == PayType.WXPay) {
			getKCoinQRCodeOfWX(req);
		}else {
			rsp.setResult(ResultTypeList.ERROR_ARGS);
			ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
			return ResultTypeList.ERROR_ARGS;
		}
		return 1;
	}



	private void getKCoinQRCodeOfWX(KCoinRechargeRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		//System.out.println("getKCoinQRCodeOfWX-----------");
		KCoinRechargeResponse rsp = new KCoinRechargeResponse();
		UserRechargeInfo uInfo = new UserRechargeInfo();
		uInfo =initUserRechargeInfoOfKCoin(req,PayType.WXPay);
		if(null==uInfo) {
			rsp.setResult(ResultTypeList.WEIXIN_EXCEPTION);
			ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
		}
		String url;
		url = MyFactory.context.getBean("WXQrcode", WXQrcode.class).getWXQrcode(uInfo,"http://"+SocketServer.adress+":8085/WXPay",ConsumptionType.BUYKCOIN);
		if (url != null) {
			rsp.setUrl(url);
			rsp.setResult(ResultTypeList.SUCCESS);
			try {
					MyFactory.context.getBean("UserRechargeDBServer", UserRechargeDBServer.class).insertUserRecharge(uInfo);
				} catch (BeansException | SQLException e) {
					rsp.setResult(ResultTypeList.INSERT_DB_EXCEPTION);
					e.printStackTrace();
					ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
					return ;
			}
		}else {			
				rsp.setResult(ResultTypeList.WEIXIN_EXCEPTION);
		}
		ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
		
		
	}



	private void getKCoinQRCodeOfAli(KCoinRechargeRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		KCoinRechargeResponse rsp = new KCoinRechargeResponse();
		UserRechargeInfo uInfo = new UserRechargeInfo();
		uInfo =initUserRechargeInfoOfKCoin(req,PayType.ALIPAY);
		if(null==uInfo) {
			rsp.setResult(ResultTypeList.ALIPAY_EXCEPTION);
			ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
			return ;
		}
		String url;
		url = MyFactory.context.getBean("AlipayQrcode", AlipayQrcode.class).getAlipayQrcode(uInfo,"http://"+SocketServer.adress+":8085/KCoinOfAli");
		if (url != null) {
			rsp.setUrl(url);
			rsp.setResult(ResultTypeList.SUCCESS);
			try {
					MyFactory.context.getBean("UserRechargeDBServer", UserRechargeDBServer.class).insertUserRecharge(uInfo);
				} catch (BeansException | SQLException e) {
					rsp.setResult(ResultTypeList.INSERT_DB_EXCEPTION);
					e.printStackTrace();
					ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
					return ;
			}
		}else {			
				rsp.setResult(ResultTypeList.ALIPAY_EXCEPTION);
		}
		ccm.sendResponse(PROTOID.KCOIN_RECHARGE_RSP, req.getMachineId(), rsp);
		
		
	}

	private void handleKpay(PayQRCodeRequest req) throws IllegalArgumentException, IllegalAccessException, BeansException, SQLException, ClientProtocolException, URISyntaxException, IOException {
		PayResultInfo pInfo=new PayResultInfo();
		UserRechargeInfo uInfo = new UserRechargeInfo();
		PayQRCodeResponse rsp = new PayQRCodeResponse();
		uInfo =initUserRechargeInfo(req,PayType.KPAY);
		if(null==uInfo) {
			rsp.setResult(ResultTypeList.UNKNOWN_FAIL);
			ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
			return;
		}
		//GetMidTradePackageInfo ginfo = GMTP.getMidPackage(req.getPacketId());
		pInfo.setkCoin(req.getkCoin());
		pInfo.setMachineId(req.getMachineId());
		pInfo.setTradeid(req.getPacketId());
		pInfo.setOpenId(req.getOpenId());
		pInfo.setPrice(uInfo.getMount());//
		//uInfo.setRecharge_status(1);
		pInfo.setOut_trade_no(Long.toString(System.currentTimeMillis()));//消费订单和充值订单不一样
		int minites = getNumFromString(uInfo.getRecharge_description());
		//System.out.println("PayQRCode minites:"+minites);
		rsp.setResult(ResultTypeList.SUCCESS);
		ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
		MyFactory.context.getBean("GetPayResult", GetPayResult.class).ntfPlayerPayStatus(pInfo,3,minites);//3表示k币支付
		MyFactory.context.getBean("GetPayResult", GetPayResult.class).ntfPHPServer(pInfo);
		MyFactory.context.getBean("GetPayResult", GetPayResult.class).insetUserConsume(uInfo);
		
		
	}



	private void getAliPayQRcode(PayQRCodeRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		UserRechargeInfo uInfo = new UserRechargeInfo();
		PayQRCodeResponse rsp = new PayQRCodeResponse();
		uInfo =initUserRechargeInfo(req,PayType.ALIPAY);
		if(null==uInfo) {
			rsp.setResult(ResultTypeList.ALIPAY_EXCEPTION);
			ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
		}
		String url;
		url = MyFactory.context.getBean("AlipayQrcode", AlipayQrcode.class).getAlipayQrcode(uInfo,"http://"+SocketServer.adress+":8085/AliPay");
		if (url != null) {
			rsp.setUrl(url);
			rsp.setResult(ResultTypeList.SUCCESS);
			try {
				if(req.getPayType()!=3) {
					MyFactory.context.getBean("UserRechargeDBServer", UserRechargeDBServer.class).insertUserRecharge(uInfo);
					}
				} catch (BeansException | SQLException e) {
					rsp.setResult(ResultTypeList.INSERT_DB_EXCEPTION);
					e.printStackTrace();
					ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
					return ;
			}
		}else {			
				rsp.setResult(ResultTypeList.ALIPAY_EXCEPTION);
		}
		rsp.setPacketId(req.getPacketId());
		ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
	}



	private UserRechargeInfo initUserRechargeInfo(PayQRCodeRequest req, int payType) {
		UserRechargeInfo uInfo = new UserRechargeInfo();
		int uid;
		try {
			uid = MyFactory.context.getBean("DBService", DBService.class).getUidByOpenId(req.getOpenId());
		} catch (BeansException | SQLException e) {
			System.out.println("GetPayQRCodeInfo getUidByOpenId :"+e);
			return null;
		}
		GetMidTradePackageInfo ginfo = GMTP.getMidPackage(req.getPacketId());
		if(null ==ginfo) {
			//System.out.println("gCodeInfo IS NULL");
			
			return null;
		}
		String out_trade_no = System.currentTimeMillis()+Integer.toString(uid);
		uInfo.setMid(req.getMachineId());
		uInfo.setMount(ginfo.getPrice());
		uInfo.setPacketId(req.getPacketId());
		//uInfo.setRecharge_day(recharge_day);
		uInfo.setRecharge_description(ginfo.getTradeName());
		if(payType==PayType.KPAY) {
			uInfo.setRecharge_status(PayState.PAYSUCC);
		}else {
			uInfo.setRecharge_status(PayState.WAITPAY);
		}
		uInfo.setRecharge_orderid(out_trade_no);
		//uInfo.setRecharge_time(recharge_time);
		uInfo.setRecharge_type(payType);
		uInfo.setUid(uid);
		return uInfo;
	}



	private void getWXPayQRCode(PayQRCodeRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		UserRechargeInfo uInfo = new UserRechargeInfo();
		PayQRCodeResponse rsp = new PayQRCodeResponse();
		uInfo = initUserRechargeInfo(req, PayType.WXPay);
		if(null==uInfo) {
			rsp.setResult(ResultTypeList.ALIPAY_EXCEPTION);
			ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
		}
		String url;
		//System.out.println("getWXPayQRCode--------");
		url = MyFactory.context.getBean("WXQrcode", WXQrcode.class).getWXQrcode(uInfo,"http://"+SocketServer.adress+":8085/WXPay",ConsumptionType.BUYPACKET);
		//System.out.println("getWXPayQRCode+++++");
		if (url != null) {
			rsp.setUrl(url);
			rsp.setResult(ResultTypeList.SUCCESS);
			try {
				if(req.getPayType()!=3) {
					MyFactory.context.getBean("UserRechargeDBServer", UserRechargeDBServer.class).insertUserRecharge(uInfo);
					}
				} catch (BeansException | SQLException e) {
					rsp.setResult(ResultTypeList.INSERT_DB_EXCEPTION);
					e.printStackTrace();
					ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
					return ;
			}
		}else {			
				rsp.setResult(ResultTypeList.WEIXIN_EXCEPTION);
		}
		rsp.setPacketId(req.getPacketId());
		ccm.sendResponse(PROTOID.PAY_QRCODE_RSP, req.getMachineId(), rsp);
		
	}
	public int getNumFromString(String recharge_description) {
		if("".equals(recharge_description)) {
			return 0;
		}
		Pattern pattern = Pattern.compile("[^0-9]");
		Matcher matcher = pattern.matcher(recharge_description);
		String result = matcher.replaceAll("");
		return Integer.parseInt(result);
	}
}
